/**
 * 2010(c) Copyright Oceansoft Information System Co.,LTD. All rights reserved.
 * <p>
 * Compile: JDK 1.6+
 * <p>
 * 版权所有(C)：江苏欧索软件有限公司
 * <p>
 * 公司名称：江苏欧索软件有限公司
 * <p>
 * 公司地址：中国苏州科技城青山路1号
 * <p>
 * 网址: http://www.oceansoft.com.cn
 * <p>
 * 作者: 090922(陈伟)
 * <p>
 * 文件名: com.oceansoft.mobile.econsole.cache.redis.CacheBaseService.java 
 * <p>
 * 类产生时间: 2014-6-10 0010 下午 16:12
 * <p>
 * 负责人: 090922(陈伟)
 * <p>
 * Email:javacspring@gmail.com
 * <p>
 * 所在组 : 掌上公安应用平台
 * <p>
 * 所在部门: 开发部--手持技术部
 * <p>
 * <p>
 */
package com.oceansoft.mobile.common.util;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * Description
 *
 * @author: chenw
 * @time: 2014-6-10 0010 下午 16:12
 */
@Component
public class CacheBaseService {
	
    private static RedisTemplate<Serializable, Object> redisTemplate ;
    private static final CacheBaseService single = new CacheBaseService();

	// 静态工厂方法
	public static CacheBaseService getInstance() {
		//System.out.println(redisTemplate);
		if(null==redisTemplate){
			redisTemplate = (RedisTemplate<Serializable, Object>)CommonUtilCache.getItem("simple");
		}
		return single;
	}
	
	

    /**
     * 使指定KEY过期
     *
     * @param key     KEY
     * @param seconds 过期时间
     */
    public void expired(String key, long seconds) {
        redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
    }

    /**
     * 保存K-V
     *
     * @param key   String 键值
     * @param value String 值
     */
    public void set(final String key, final String value) {
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                redisConnection.set(serializer.serialize(key), serializer.serialize(value));
                return null;
            }
        });
    }

    /**
     * 保存KEY-VALUE
     *
     * @param key            KEY
     * @param expiredSeconds 过期时间
     */
    public void set(final String key, final long expiredSeconds, final String value) {
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.setEx(serializer.serialize(key), expiredSeconds, serializer.serialize(value));
                return null;
            }
        });
    }

    /**
     * 返回指定KEY过期时间，<br>如果KEY不存在，则过期时间返回-2，<br>如果在保存时未指定过期时间，则此KEY的过期时间返回-1
     *
     * @param key KEY
     * @return 过期时间
     */
    public long getExpires(final String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 判断KEY是否存在
     *
     * @param key 返回true表示存在 反之返回false
     * @return boolean
     */
    public boolean exists(final String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * 获取指定KEY的值
     *
     * @param key KEY
     * @return String返回值为String类型
     */
    public String get(final String key) {
        return redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                byte[] _val = redisConnection.get(serializer.serialize(key));
                if (null == _val) {
                    return null;
                }
                return serializer.deserialize(_val);
            }
        });
    }

    /**
     * 保存对象
     *
     * @param object 实体对象
     */
    public void cache(final String key, final Object object) {
    	
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(JSON.toJSONString(object)));
                return null;
            }
        });
    }

    /**
     * @param key     缓存KEY
     * @param object  缓存对象
     * @param expires 过期时间(单位为天)
     */
    public void cache(final String key, final Object object, final float expires) {
        cache(key, object, (long) expires * 24 * 3600);
    }

    /**
     * @param key     缓存KEY
     * @param object  缓存对象
     * @param expires 过期时间(单位为秒)
     */
    public void cache(final String key, final Object object, final long expires) {
    	try
    	{
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.setEx(serializer.serialize(key), expires, serializer.serialize(JSON.toJSONString(object)));
                return null;
            }
        });
    	}
    	catch(Exception e)
    	{
    		System.out.println(e.getLocalizedMessage());
    	}
    }

    /**
     * @param key     缓存KEY
     * @param object  缓存对象
     * @param expires 过期时间(单位为秒)
     */
    public void cache(final String key, final String object, final long expires) {
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.setEx(serializer.serialize(key), expires, serializer.serialize(object));
                return null;
            }
        });
    }

    /**
     * 从缓存中获取对象
     *
     * @param key 对象KEY
     * @return <T> 实体对象
     */
    public Object getObject(final String key) {
        return getObject(key, Object.class);
    }

    /**
     * 从缓存中获取对象
     *
     * @param key 对象KEY
     * @return <T> 实体对象
     */
    public <T> T getObject(final String key, final Class<T> clazz) {
        return redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                return JSON.parseObject(serializer.deserialize(connection.get(serializer.serialize(key))), clazz);
            }
        });
    }

    public String cacheStringAuto(String key, CacheCallback<String> callback, float expireDay) {
        if (exists(key)) {
            String value = get(key);
            System.out.println("\n\nFrom Cache==>" + key + "\n\n");
            return JSON.parse(get(key)).toString();
        } else {
            String obj = callback.getCacheValue();
            if (StringUtils.isNotBlank(obj))
                cache(key, obj, expireDay);
            return obj;
        }
    }

    public <T> T cacheObjectAuto(String key, CacheCallback<T> callback, float expireDay, Class<T> clazz) {
        if (exists(key)) {
            return getObject(key, clazz);
        } else {
            T obj = callback.getCacheValue();
            if (null != obj)
                cache(key, obj, expireDay);
            return obj;
        }
    }

    public JSONObject cacheJSONAuto(String key, CacheCallback<JSONObject> callback, float expireDay) {
        if (exists(key)) {
            String value = get(key);
            System.out.println("\n\nFrom Cache==>" + key + "\n\n");
            if (StringUtils.isNotBlank(value) && !"\"\"".equals(value))
                return JSON.parseObject(get(key));
            return null;
        } else {
            JSONObject obj = callback.getCacheValue();
            if (null != obj)
                cache(key, obj, expireDay);
            else
                cache(key, "", 30);//空值缓存10s
            return obj;
        }
    }

    public void delCache(final String key) {
        redisTemplate.execute(new RedisCallback<Void>() {
            @Override
            public Void doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                connection.del(serializer.serialize(key));
                return null;
            }
        });
    }

    public interface CacheCallback<T> {
        public T getCacheValue();
    }
}
